package resilienceManager.qmul.gemom;


/**
 * The search thread class
 * 
 * COPYRIGHT DISCLAIMER
 * Synopsis: All the source codes presented in this document are intellectual
 * properties of Queen Mary, University of London.
 * 
 * @year 2010
 * @author Peng Jiang, John Bigham, Jiayi Wu, Jinfu Wang------------QMUL
 * @version 1.0 
 */



public class SearchThread extends Thread {

	public static final int CREATED = 0;
	public static final int RUNNING = 1;
	public static final int ENTERING_MONITOR = 2;
	public static final int RUNNING_MONITOR = 3;
	public static final int LEAVING_MONITOR = 4;
	public static final int WAITING_CONDITION = 5;
	public static final int SIGNALING_CONDITION = 6;
	public static final int DEAD = 7;

	/**
	 * The monitor used by the thread.
	 */
	private Object monitor;

	/**
	 * The state of the thread.
	 */
	private volatile int state;


	/**
	 * Creates a DemoThread object.
	 * @param monitor the monitor used by the thread
	 */
	public SearchThread( Object monitor )
	{
		this.monitor = monitor;
		state = CREATED;
	}

	/**
	 * Runs the thread.
	 */
	public void run()
	{
		state = RUNNING;
		while ( true ) {
			switch ( state ) {
			case ENTERING_MONITOR:
				synchronized ( monitor ) { runMonitor(); }
				break;
			case DEAD:
				return;
			}
			state = RUNNING;
			/*
			try { 
				sleep( 100 ); 
			}
			catch ( InterruptedException e ) {}
			*/
		}
	}

	/**
	 * Runs the thread in the monitor.
	 */
	public void runMonitor()
	{
		state = RUNNING_MONITOR;
		while ( true ) {
			switch ( state ) {
			case WAITING_CONDITION:
				try { monitor.wait(); }
				catch ( InterruptedException e ) {}
				break;
			case SIGNALING_CONDITION:
				monitor.notify();
				break;
			case LEAVING_MONITOR:
				return;
			}
			state = RUNNING_MONITOR;
			/*
			try { 
				sleep( 100 ); 
			}
			catch ( InterruptedException e ) {}
			*/
		}
	}

	/**
	 * Returns the state of the thread.
	 */
	public int getcurrentState()
	{
		return state;
	}
	/**
	 * Tells the thread to enter the monitor.
	 */
	public void enterMonitor()
	{
		state = ENTERING_MONITOR;
	}

	/**
	 * Tells the thread to leave the monitor.
	 */
	public void leaveMonitor()
	{
		state = LEAVING_MONITOR;
	}

	/**
	 * Tells the thread to wait for the condition.
	 */
	public void waitCondition()
	{
		state = WAITING_CONDITION;
	}

	/**
	 * Tells the thread to signal the condition.
	 */
	public void signalCondition()
	{
		state = SIGNALING_CONDITION;
	}

	/**
	 * Tells the thread to terminate.
	 */
	public void terminate()
	{
		state = DEAD;
	}

}
